function init() {

  // jQuery ext.
  (function($) {
    $.fn.getTextareaCursorPosition = function() {
      var p = 0;
      var el = $(this).get(0);
      if (document.selection) {
        // IE
        el.focus();
        var sel = document.selection.createRange();
        var sel_len = sel.text.length;
        sel.moveStart('character', -el.value.length);
        p = sel.text.length - sel_len;
      } else if (el.selectionStart || el.selectionStart === 0) {
        // FF
        p = el.selectionStart;
      } else {
        // ?
        return {line: 0, col: 0};
      }
      var v = el.value.substr(0, p).split('\n');
      var l = v.length;
      var c = v[l-1].length;
      return {line: l, col: c + 1};
    };
  }(jQuery));
  // /ext.

  var error_panel = $('#error_panel');
  var w = $(window);
  var d = new database();
  var ed = new examples_database($('#examples'));
  var e = new executor($('#canvas').get(0), w.width(), w.height(), $.proxy(function(text) {
    this.element.text(text);
    this.element.show();
    //L('EXCEPTION CALL BACK: ' + text);
  }, {
    element: error_panel
  }));

  $('#editor').show();

  var editor = $('#editor');
  var viewer = $('#viewer');
  var textarea = $('#textarea');
  var status = $('#status');

  var ex_ps = $.proxy(function() {
    setTimeout($.proxy(function() {
      var p = this.textarea.getTextareaCursorPosition();
      this.status.text(p.line + ':' + p.col);
    }, this), 100);
  }, {
    textarea: textarea,
    status: status
  });

  textarea.keydown(ex_ps).mouseup(ex_ps).show(ex_ps);

  var px_e = $.proxy(function() {
    // this.viewer.hide(); // TODO: stop playing
    this.editor.show();
    this.textarea.focus();
  }, {
    editor: editor,
    viewer: viewer,
    textarea: textarea
  });

  $('#edit_button').click(px_e);

  var px_v = $.proxy(function() {
    this.editor.hide();
    this.error_panel.hide();
    this.viewer.show();
    this.executor.load(this.textarea.val());
  }, {
    executor: e,
    error_panel: error_panel,
    editor: editor,
    viewer: viewer,
    textarea: textarea
  });

  $('#play_button').click(px_v);

  $(document).keydown($.proxy(function(e) {
//    L(e.which);
    if (e.ctrlKey) {
      if (e.which === 13) {
        (this.editor.is(':visible') ? this.px_v : this.px_e)();
        e.preventDefault();
      }
    }
  }, {
    px_e: px_e,
    px_v: px_v,
    editor: editor
  }));

  var saver = $('#saver');
  var save_name = $('#save_name');
  $('#save_dialog_button').click($.proxy(function() {
    this.saver.show();
    this.save_name.val(this.database.last_key);
  }, {
    database: d,
    saver: saver,
    save_name: save_name
  }));


  // Keep functions out of the loop.
  // Подумать об этом.
  // Это результат не очень удачного дизайна.
  var out_loop_load = function() {
    this.textarea.val(this.database.load(this.name));
    this.loader.hide();
  };
  var out_loop_remove = function() {
    this.one.database.remove(this.name);
    this.one.px_l();
  };
  // /

  var loader = $('#loader');
  var load_list = $('#load_list');
  var px_l = function() {
    var l = this.database.list();
    this.loader.show();
    this.load_list.empty();
    for (var i = 0; i < l.length; ++i) { // > ----
      var n = l[i];
      this.load_list.append($('<div></div>').addClass('button').text(n).click($.proxy(out_loop_load, {
        name: n,
        database: this.database,
        loader: this.loader,
        textarea: this.textarea
      })).append($('<div></div>').addClass('button_del').click($.proxy(out_loop_remove, {
        name: n,
        one: this
      }))));
    }
  };
  $('#load_dialog_button').click($.proxy(px_l, {
    database: d,
    loader: loader,
    load_list: load_list,
    textarea: textarea,
    px_l: px_l
  }));

  $('#load_ex_dialog_button').click($.proxy(function() {
    var l = this.database.list();
    var t = this.database.load(l[0]);
    this.loader.show();
    this.load_list.empty();
    for (var i = 0; i < l.length; ++i) { // > ----
      var n = l[i];
      this.load_list.append($('<div></div>').
        addClass('button').text(n).click($.proxy(
          out_loop_load, {
            name: n,
            database: this.database,
            loader: this.loader,
            textarea: this.textarea
          }
        ))
      );
    }
  }, {
    database: ed,
    loader: loader,
    load_list: load_list,
    textarea: textarea
  }));

  $('#cancel_load_button').click($.proxy(function() {
    this.loader.hide();
  }, {loader: loader}));

  $('#save_button').click($.proxy(function() {
    this.database.save_as(this.save_name.val(), this.textarea.val());
    this.saver.hide();
  }, {
    database: d,
    saver: saver,
    save_name: save_name,
    textarea: textarea
  }));

  $('#cancel_save_button').click($.proxy(function() {
    this.saver.hide();
  }, {saver: saver}));

  var help = $('#help');
  $('#help_button').click($.proxy(function() {
    this.help.show();
  }, {help: help}));

  $('#cancel_help_button').click($.proxy(function() {
    this.help.hide();
  }, {help: help}));

  w.resize($.proxy(function() {
    this.executor.resize_handler(this.window.width(), this.window.height());
  }, {
    executor: e,
    window: w
  }));

  $('[contenteditable=true]').focus(); // TODO:-)
}
